package com.fjsaas.flyway;

import java.util.Map;

import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.callback.FlywayCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.fjsaas.quartz.MysqlTask;
import com.fjsaas.quartz.QuartzTaskService;
import com.fjsaas.quartz.TaskDetail;
import com.fjsaas.web.constants.Constants;
import com.fjsaas.web.utils.MyUtil;

public class FlywayMigrate {

	private String url;
	private String password;
	private String username;
	private String[] locations;
	private String table = "schema_version";
	private String encoding = "UTF-8";
	private boolean autoRepair = false;
	private FlywayCallback flywayCallback;
	private String runtimeEnvironment;
	private QuartzTaskService quartzTaskService;

	public static final String DEVELOP_MODE = "develop";
	public static final String TEST_MODE = "test";
	public static final String DEPLOY_MODE = "deploy";
	private static Logger logger = LoggerFactory.getLogger(FlywayMigrate.class);

	public void migrate() {

		Map<String, String> map = MyUtil.parseJdbcUrl(url);
		String jdbcUrl = map.get("jdbcUrl");
		String schema = map.get("dbName");

		if (StringUtils.isEmpty(jdbcUrl) || StringUtils.isEmpty(schema)) {
			throw new RuntimeException("url连接字符串解析失败");
		}

		// Create the Flyway instance
		Flyway flyway = new Flyway();
		if (flywayCallback != null && DEPLOY_MODE.equals(runtimeEnvironment)) {
			flyway.setCallbacks(flywayCallback);
		}

		// Point it to the database
		flyway.setDataSource(jdbcUrl, username, password);
		flyway.setSchemas(schema);
		flyway.setTable(table);
		flyway.setEncoding(encoding);
		flyway.setLocations(locations);
		try {
			flyway.migrate();
		} catch (FlywayException e) {
			if (autoRepair) {
				// 迁移失败，那么自动修复schema-version，避免迁移一旦失败就要重新构造数据库
				flyway.repair();
			}
			e.printStackTrace();
		}

		if (quartzTaskService != null) {
			TaskDetail taskDetail = new TaskDetail("mysql定时备份", "mysql_task", MysqlTask.class, Constants.CRON_EXPRESSION);
			try {
				quartzTaskService.runTask(taskDetail);
			} catch (Exception e) {
				logger.error("mysql定时备份失败：", e);
			}
		}
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getTable() {
		return table;
	}

	public void setTable(String table) {
		this.table = table;
	}

	public String[] getLocations() {
		return locations;
	}

	public void setLocations(String[] locations) {
		this.locations = locations;
	}

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public boolean isAutoRepair() {
		return autoRepair;
	}

	public void setAutoRepair(boolean autoRepair) {
		this.autoRepair = autoRepair;
	}

	public FlywayCallback getFlywayCallback() {
		return flywayCallback;
	}

	public void setFlywayCallback(FlywayCallback flywayCallback) {
		this.flywayCallback = flywayCallback;
	}

	public String getRuntimeEnvironment() {
		return runtimeEnvironment;
	}

	public void setRuntimeEnvironment(String runtimeEnvironment) {
		this.runtimeEnvironment = runtimeEnvironment;
	}

	public QuartzTaskService getQuartzTaskService() {
		return quartzTaskService;
	}

	public void setQuartzTaskService(QuartzTaskService quartzTaskService) {
		this.quartzTaskService = quartzTaskService;
	}

}
